package com.ifd.gui.as400;

import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.StringTokenizer;

import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.UIManager;

import org.apache.log4j.Logger;
import org.apache.log4j.PropertyConfigurator;

import com.ibm.as400.access.AS400;
import com.ibm.as400.access.AS400Message;
import com.ibm.as400.access.AS400Text;
import com.ibm.as400.access.CharConverter;
import com.ibm.as400.access.IFSFileOutputStream;
import com.ibm.as400.access.ProgramCall;
import com.ibm.as400.access.QSYSObjectPathName;
import com.ifd.as400.IFDConnectionPool;
import com.ifd.as400.IFDException;
import com.ifd.controller.SplfDefaultProperties;
import com.ifd.core.api.GenAS400Function;
import com.ifd.gui.JTextFieldLimit;

public class VSpooledFileUpload extends JDialog implements ActionListener,
		KeyListener {

	static final Logger logger = Logger.getLogger(VSpooledFileUpload.class);

	private JTextField jtfSplfName;
	private JTextField jtfUserData;
	private JTextField jtfFormType;
	private JTextField jtfOuqLib;
	private JTextField jtfOutq;
	private JTextField jtfPageWidth;
	private JTextField jtfPageLength;
	private JTextArea textArea;

	/**
	 * Create the dialog
	 */
	public VSpooledFileUpload(JTextArea txtArea) {
		super();
		setSize(new Dimension(250, 357));
		buildLayout();
		setLocationRelativeTo(null);
		setTitle("Send Spooled File To Server");

		final JLabel spoolPageLabel = new JLabel();
		spoolPageLabel.setText("Spool Page");
		spoolPageLabel.setBounds(10, 210, 215, 14);
		getContentPane().add(spoolPageLabel);

		final JLabel lengthLabel = new JLabel();
		lengthLabel.setText("Length");
		lengthLabel.setBounds(20, 230, 80, 20);
		getContentPane().add(lengthLabel);

		jtfPageLength = new JTextField();
		jtfPageLength.setText("66");
		jtfPageLength.setBounds(105, 230, 100, 20);
		getContentPane().add(jtfPageLength);

		final JLabel widthLabel = new JLabel();
		widthLabel.setText("Width");
		widthLabel.setBounds(20, 255, 80, 20);
		getContentPane().add(widthLabel);

		jtfPageWidth = new JTextField();
		jtfPageWidth.setText("132");
		jtfPageWidth.setBounds(105, 255, 100, 20);
		getContentPane().add(jtfPageWidth);
		textArea = txtArea;
	}

	private void buildLayout() {
		getContentPane().setLayout(null);

		final JLabel selectSpoolOutq = new JLabel();
		selectSpoolOutq.setText("Specify The Output Queue");
		selectSpoolOutq.setBounds(10, 10, 215, 20);
		getContentPane().add(selectSpoolOutq);

		final JLabel outputQueueLabel = new JLabel();
		outputQueueLabel.setText("Output queue");
		outputQueueLabel.setBounds(20, 35, 80, 20);
		getContentPane().add(outputQueueLabel);

		jtfOutq = new JTextField();
		jtfOutq.setBounds(105, 35, 100, 20);
		jtfOutq.setDocument(new JTextFieldLimit(10, true));
		getContentPane().add(jtfOutq);

		JLabel libraryLabel = new JLabel();
		libraryLabel.setText("Library");
		libraryLabel.setBounds(30, 60, 70, 20);
		getContentPane().add(libraryLabel);

		jtfOuqLib = new JTextField();
		jtfOuqLib.setDocument(new JTextFieldLimit(10, true));
		jtfOuqLib.setBounds(105, 60, 100, 20);
		jtfOuqLib.setText("*LIBL");

		getContentPane().add(jtfOuqLib);

		final JLabel orSelectByLabel = new JLabel();
		orSelectByLabel.setText("Specify The Spool Attributes");
		orSelectByLabel.setBounds(10, 100, 215, 20);
		getContentPane().add(orSelectByLabel);

		final JLabel spoolFileNameLabel = new JLabel();
		spoolFileNameLabel.setText("Spool File Name");
		spoolFileNameLabel.setBounds(20, 125, 80, 20);
		getContentPane().add(spoolFileNameLabel);

		jtfSplfName = new JTextField();
		jtfSplfName.setBounds(105, 125, 100, 20);
		jtfSplfName.setDocument(new JTextFieldLimit(10, true));
		jtfSplfName.setText("SPLEDITOR");
		getContentPane().add(jtfSplfName);

		final JLabel formTypeLabel = new JLabel();
		formTypeLabel.setText("Form type");
		formTypeLabel.setBounds(20, 150, 80, 20);
		getContentPane().add(formTypeLabel);

		jtfFormType = new JTextField();
		jtfFormType.setBounds(105, 150, 100, 20);
		jtfFormType.setDocument(new JTextFieldLimit(10));
		jtfFormType.setText("*STD");
		getContentPane().add(jtfFormType);

		final JLabel userDataLabel = new JLabel();
		userDataLabel.setText("User Data");
		userDataLabel.setBounds(20, 175, 80, 20);
		getContentPane().add(userDataLabel);

		jtfUserData = new JTextField();
		jtfUserData.setBounds(105, 175, 100, 20);
		jtfUserData.setDocument(new JTextFieldLimit(10));
		jtfUserData.setText("");
		getContentPane().add(jtfUserData);

		final JButton jbtLoad = new JButton("Send");
		jbtLoad.setBounds(10, 288, 90, 25);
		jbtLoad.addActionListener(this);
		jbtLoad.setMnemonic(KeyEvent.VK_L);
		jbtLoad.setActionCommand("send");
		getContentPane().add(jbtLoad);

		final JButton jbtCancel = new JButton("Cancel");
		jbtCancel.setMnemonic(KeyEvent.VK_C);
		jbtCancel.setBounds(115, 288, 90, 25);
		jbtCancel.setActionCommand("cancel");
		jbtCancel.addActionListener(this);
		getContentPane().add(jbtCancel);
	}

	public void actionPerformed(ActionEvent e) {
		try {
			// TODO Auto-generated method stub
			String command = e.getActionCommand();
			if (command.equalsIgnoreCase("cancel")) {
				this.dispose();
			} else if (command.equalsIgnoreCase("send")) {
				uploadSpooledFile();
				this.dispose();
			}
		} catch (Exception ex) {
			JOptionPane.showMessageDialog(null, ex.getLocalizedMessage(),
					"Spooled File Upload", JOptionPane.OK_OPTION);
		}
	}

	private void uploadSpooledFile() throws Exception {
		if (!validateUpload())
			return;

		ProgramCall pgm = new ProgramCall(IFDConnectionPool.getAS400());
		String pagWid = jtfPageWidth.getText();
		String pagLen = jtfPageLength.getText();
		if (pagWid.trim().length() <= 0)
			pagWid = "132";
		if (pagLen.trim().length() <= 0)
			pagLen = "66";

		QSYSObjectPathName qtempFile=
			new QSYSObjectPathName("/QSYS.LIB/QGPL.LIB/SPEDITOR.FILE/"+
				IFDConnectionPool.getAS400().getUserId().trim()+".MBR");
		GenAS400Function.qcmdexc(pgm, "CRTPF FILE("+qtempFile.getLibraryName()+
				"/"+qtempFile.getObjectName()+") RCDLEN("+jtfPageWidth.getText() + ") MAXMBRS(*NOMAX)");
		GenAS400Function.qcmdexc(pgm, "ADDPFM FILE("+qtempFile.getLibraryName()+
				"/"+qtempFile.getObjectName()+") MBR("+IFDConnectionPool.getAS400().getUserId().trim()+")");
		
		String ifsFile = parsePCtoQTEMPFile(qtempFile.getPath());

		String command = "OVRPRTF FILE(QSYSPRT) PAGESIZE(" + pagLen + " " + pagWid
				+ " *ROWCOL) " + "CTLCHAR(*FCFC) OUTQ("
				+ jtfOuqLib.getText().trim() + "/" + jtfOutq.getText().trim()
				+ ") FORMTYPE(" + jtfFormType.getText() + ") USRDTA("
				+ jtfUserData.getText() + ") " + "SPLFNAME("
				+ jtfSplfName.getText() + ") OVRSCOPE(*JOB)";
		if(!GenAS400Function.qcmdexc(pgm, command, logger))
		{
			AS400Message msgs[] = pgm.getMessageList();
			String mess="";
			for (AS400Message msg : msgs) {
				mess.concat(msg.getText().concat("\n"));
			}
			JOptionPane.showMessageDialog(null, mess,
					"Error", JOptionPane.OK_OPTION);
			return;
		}

		if(!GenAS400Function.qcmdexc(pgm,
				"CPYF FROMFILE("+qtempFile.getLibraryName().trim()+"/"+
				qtempFile.getObjectName().trim()+") TOFILE(QSYSPRT) FROMMBR(" +
				qtempFile.getMemberName().trim()+") MBROPT(*REPLACE)",
				logger))
		{
			AS400Message msgs[] = pgm.getMessageList();
			String mess="";
			for (AS400Message msg : msgs) {
				mess.concat(msg.getText().concat("\n"));
			}
			JOptionPane.showMessageDialog(null, mess,
					"Error", JOptionPane.OK_OPTION);
			return;
		}

		JOptionPane.showMessageDialog(null, "The spool file is sent.",
				"Spooled File Upload", JOptionPane.OK_OPTION);
	}

	private String parsePCtoQTEMPFile(String ifsFile) throws IFDException {
		AS400 as400 = IFDConnectionPool.getAS400();
		ProgramCall pgm = new ProgramCall(as400);
		IFSFileOutputStream os = null;
		try {
			os = new IFSFileOutputStream(as400, ifsFile);
			int curPage = 0;
			int pageLength = 66;
			try {
				pageLength = Integer.parseInt(jtfPageLength.getText());
			} catch (Exception e) {
				pageLength = 66;
			}

			InputStream in = new InputStream() {
				String s = textArea.getText();
				int inPtr = 0;

				@Override
				public int read() throws IOException {
					if (inPtr >= s.length())
						return -1;
					else {
						inPtr++;
						return s.charAt(inPtr - 1);
					}
				}
			};
			BufferedReader reader = new BufferedReader(
					new InputStreamReader(in));
			int spaceBefore = 0;
			int curLine = 0;
			String lineData = reader.readLine();
			int pagWid=Integer.parseInt(jtfPageWidth.getText());
			AS400Text converter = new AS400Text(pagWid,37,IFDConnectionPool.getAS400());
			while (lineData != null) {
				if (curLine > curPage * pageLength) {
					os.write(converter.toBytes("1"));
					curPage++;
					spaceBefore = 0;
				}
				if (lineData.trim().length() <= 0) {
					spaceBefore++;
				} else {
					int dev = spaceBefore / 3;
					int rem = spaceBefore % 3;
					for (int j = 0; j < dev; j++)
						os.write(converter.toBytes("-"));

					switch (rem) {
					case 2:
						os.write(converter.toBytes("-"+lineData));
						break;
					case 1:
						os.write(converter.toBytes("0"+lineData));
						break;
					case 0:
						os.write(converter.toBytes(" "+lineData));
						break;
					}
					spaceBefore = 0;
				}
				curLine++;
				lineData = reader.readLine();
			}
		} catch (Exception e) {
			throw new IFDException(e.getLocalizedMessage(), logger);
		} finally {
			try {
				if (os != null)
					os.close();
			} catch (Exception e2) {
			}
		}
		return ifsFile;
	}

	private boolean validateUpload() throws Exception {
		if (jtfOutq.getText().length() <= 0)
			throw new Exception("Output queue name must not be blank");
		if (jtfSplfName.getText().length() <= 0)
			throw new Exception("Spool file name must not be blank");
		if (!GenAS400Function.isObjectExist(jtfOuqLib.getText(), jtfOutq
				.getText(), "OUTQ"))
			throw new Exception("Output queue " + jtfOutq.getText()
					+ " in library " + jtfOuqLib.getText() + " doesn't exist");
		return true;
	}

	public void keyPressed(KeyEvent e) {
		int key = e.getKeyCode();
		if (key == KeyEvent.VK_ENTER) {
			try {
				uploadSpooledFile();
				this.dispose();
			} catch (Exception e2) {
				JOptionPane.showMessageDialog(null, e2.getLocalizedMessage(),
						"Spooled File Upload", JOptionPane.OK_OPTION);
			}
		}
	}

	public void keyReleased(KeyEvent e) {
		// TODO Auto-generated method stub

	}

	public void keyTyped(KeyEvent e) {
		// TODO Auto-generated method stub

	}
}
